#ifndef FUN_H
#define FUN_H


#include <netinet/in.h>
#include<arpa/inet.h>
#include <qfile.h>
#include"iostream"
#include <qtextstream.h>
#include <QQueue>
#include <qstring.h>
#include<pthread.h>

#include "pcap.h"
#include <QVector>
#include <QThread>
#include "mythread.h"
#include "semaphore.h"
#include <QApplication>

int start_times=0;
bool open_close=false; bool process_or_not=false;
int arpntmp=0; int icmpntmp=0; int tcpntmp=0; int udpntmp=0;
double cap_stime=0;

pthread_mutex_t mylock=PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex1=PTHREAD_MUTEX_INITIALIZER;
sem_t mutex2;
int tcpchart=0;
int ipchart=0;
int udpchart=0;
int capture_num=1;

struct ether_header
{
    u_int8_t ether_dhost[6];
    /* 目的以太网地址 */
    u_int8_t ether_shost[6];
    /* 源以太网地址 */
    u_int16_t ether_type;
public:
    ether_header& operator =(const ether_header& h)
    {
        //ether_dhost[6]=h.ether_dhost[6];
        memcpy(ether_dhost,h.ether_dhost,6);
        memcpy(ether_shost,h.ether_shost,6);
        //ether_shost=h.ether_shost;
        ether_type=h.ether_type;
        return *this;
    }
    QString Getether_dhost()
    {
        QString str;
        str.sprintf("%02X:%02X:%02X:%02X:%02X:%02X",ether_dhost[0],ether_dhost[1],ether_dhost[2],ether_dhost[3],ether_dhost[4],ether_dhost[5]);
        return str;
    }
    QString Getether_shost()
    {
        QString str;
        str.sprintf("%02X:%02X:%02X:%02X:%02X:%02X",ether_shost[0],ether_shost[1],ether_shost[2],ether_shost[3],ether_shost[4],ether_shost[5]);
        return str;
    }
    QString Getether_type()
    {
        QString str;
        switch (ether_type)
        {
            case 0x0800:
            {
                str.sprintf("0x0800 IP");
            }
                break;
            case 0x0806:
            {
                str.sprintf("0x0806 ARP");

            }
                break;
            case 0x8035:
                str.sprintf("0x8035 RARP");
                break;
            default:
                str.sprintf("0x%04X",ether_type);
                break;
        }
        return str;
    }
    QTreeWidgetItem * Gettree(){
        QTreeWidgetItem *note = new QTreeWidgetItem(QStringList("ETHERNET HEADER"));
        QTreeWidgetItem *childtree1 = new QTreeWidgetItem(QStringList(Getether_dhost()));
        QTreeWidgetItem *childtree2 = new QTreeWidgetItem(QStringList(Getether_shost()));
        QTreeWidgetItem *childtree3 = new QTreeWidgetItem(QStringList(Getether_type()));
        note->addChild(childtree1);
        note->addChild(childtree2);
        note->addChild(childtree3);
        return note;
    }
    /* 以太网类型 */
};

/* 下面是IP地址格式的定义 */

/*
typedef u_int32_t in_addr_t;
struct in_addr
{
    in_addr_t s_addr;
};
*/

//struct in_addr1
//{
//    struct
//        {
//            u_char s_b1,s_b2,s_b3,s_b4;
//        } S_un_b;
//};
/*
-----------------------------------------------------------------------------------------------------------------------
下面是ARP协议格式的定义
-----------------------------------------------------------------------------------------------------------------------
 */
struct arp_header
{
    u_int16_t arp_hardware_type;
    /* 硬件类型 */
    u_int16_t arp_protocol_type;
    /* 协议类型 */
    u_int8_t arp_hardware_length;
    /* 硬件地址长度 */
    u_int8_t arp_protocol_length;
    /* 协议地址长度 */
    u_int16_t arp_operation_code;
    /* ARP操作码 */
    u_int8_t arp_source_ethernet_address[6];
    /* 源以太网地址 */
    u_int8_t arp_source_ip_address[4];
    /* 源IP地址 */
    u_int8_t arp_destination_ethernet_address[6];
    /* 目的以太网地址 */
    u_int8_t arp_destination_ip_address[4];
    /* 目的IP地址 */
public:
    arp_header& operator =(const arp_header& h)
    {
        arp_hardware_length=h.arp_hardware_length;
        arp_hardware_type=h.arp_hardware_type;
        arp_protocol_length=h.arp_protocol_length;
        arp_protocol_type=h.arp_protocol_type;
        arp_operation_code=h.arp_operation_code;
        memcpy(arp_source_ethernet_address,h.arp_source_ethernet_address,6);
        memcpy(arp_source_ip_address,h.arp_source_ip_address,4);
        memcpy(arp_destination_ethernet_address,h.arp_destination_ethernet_address,6);
        memcpy(arp_destination_ip_address,h.arp_destination_ip_address,4);
        return *this;
    }
    QString Getarp_source_ethernet_address()
    {
        QString str;
        str.sprintf("%02X:%02X:%02X:%02X:%02X:%02X",arp_source_ethernet_address[0],arp_source_ethernet_address[1],arp_source_ethernet_address[2],arp_source_ethernet_address[3],arp_source_ethernet_address[4],arp_source_ethernet_address[5]);
        return str;
    }
    QString Getarp_destination_ethernet_address()
    {
        QString str;
        str.sprintf("%02X:%02X:%02X:%02X:%02X:%02X",arp_destination_ethernet_address[0],arp_destination_ethernet_address[1],arp_destination_ethernet_address[2],arp_destination_ethernet_address[3],arp_destination_ethernet_address[4],arp_destination_ethernet_address[5]);
        return str;
    }
    QString Getarp_source_ip_address()
    {
        QString str;
        struct in_addr ip_address;
        memcpy((void*) &ip_address, (void*) &arp_source_ip_address, sizeof(struct in_addr));
        str.sprintf("%s", inet_ntoa(ip_address));
        return str;
    }
    QString Getarp_destination_ip_address()
    {
        QString str;
        struct in_addr ip_address;
        memcpy((void*) &ip_address, (void*) &arp_destination_ip_address, sizeof(struct in_addr));
        str.sprintf("%s", inet_ntoa(ip_address));
        return str;
    }
    QString Getarp_hardware_type()
    {
        QString str;
        str.sprintf("ARP Hardware %d",  ntohs(arp_hardware_type));
        /* 获得硬件类型 */
        return str;
    }
    QString Getarp_protocol_type()
    {
        QString str;
        str.sprintf("ARP Protocol Type %d",  ntohs(arp_protocol_type));
          /* 获得协议类型 */
        return str;
    }
    QString Getarp_hardware_length()
    {
        QString str;
        str.sprintf("ARP Hardware Length:%d", arp_hardware_length);
          /* 获得硬件地址长度 */
        return str;
    }
    QString Getarp_protocol_length()
    {
        QString str;
        str.sprintf("ARP Protocol Length:%d", arp_protocol_length);
           /* 获得协议地址长度 */
        return str;
    }
    QString Getarp_operation_code()
    {
        QString str;
        str.sprintf("ARP Operation:%d",  ntohs(arp_operation_code));
          /* 获得协议类型 */
        return str;
    }
    QTreeWidgetItem * Gettree(){
        QTreeWidgetItem *note = new QTreeWidgetItem(QStringList("ARP HEADER"));
        QTreeWidgetItem *childtree1 = new QTreeWidgetItem(QStringList(Getarp_hardware_type()));
        QTreeWidgetItem *childtree2 = new QTreeWidgetItem(QStringList(Getarp_protocol_type()));
        QTreeWidgetItem *childtree3 = new QTreeWidgetItem(QStringList(Getarp_hardware_length()));
        QTreeWidgetItem *childtree4 = new QTreeWidgetItem(QStringList(Getarp_protocol_length()));
        QTreeWidgetItem *childtree5 = new QTreeWidgetItem(QStringList(Getarp_operation_code()));
        QTreeWidgetItem *childtree6 = new QTreeWidgetItem(QStringList(Getarp_source_ethernet_address()));
        QTreeWidgetItem *childtree7 = new QTreeWidgetItem(QStringList(Getarp_source_ip_address()));
        QTreeWidgetItem *childtree8 = new QTreeWidgetItem(QStringList(Getarp_destination_ethernet_address()));
        QTreeWidgetItem *childtree9 = new QTreeWidgetItem(QStringList(Getarp_destination_ip_address()));
        note->addChild(childtree1);
        note->addChild(childtree2);
        note->addChild(childtree3);
        note->addChild(childtree4);
        note->addChild(childtree5);
        note->addChild(childtree6);
        note->addChild(childtree7);
        note->addChild(childtree8);
        note->addChild(childtree9);
        return note;
    }
};
/*
-----------------------------------------------------------------------------------------------------------------------
下面是IP协议格式的定义
-----------------------------------------------------------------------------------------------------------------------
 */
struct ip_header
{
#if defined(WORDS_BIGENDIAN)
    u_int8_t ip_version: 4,
        /* 版本 */
        ip_header_length: 4;
    /* 首部长度 */
#else
    u_int8_t ip_header_length: 4,
        /* 首部长度 */
        ip_version: 4;
    /* 版本 */
#endif
    u_int8_t ip_tos;
    /* 服务质量 */
    u_int16_t ip_length;
    /* 总长度 */
    u_int16_t ip_id;
    /* 标识 */
    u_int16_t ip_off;
    /* 偏移 */
    u_int8_t ip_ttl;
    /* 生存时间 */
    u_int8_t ip_protocol;
    /* 协议类型 */
    u_int16_t ip_checksum;
    /* 校验和 */
    struct in_addr ip_souce_address;
    /* 源IP地址 */
    struct in_addr ip_destination_address;
    /* 目的IP地址 */
public:
    ip_header& operator =(const ip_header& h)
    {
        ip_header_length=h.ip_header_length;
        ip_version=h.ip_version;
        ip_tos=h.ip_tos;
        ip_length=h.ip_length;
        ip_id=h.ip_id;
        ip_off=h.ip_off;
        ip_protocol=h.ip_protocol;
        ip_checksum=h.ip_checksum;
        ip_souce_address=h.ip_souce_address;
        ip_destination_address=h.ip_destination_address;
        return *this;
    }
    QString Getip_souce_address()
    {
        QString str;
        str.sprintf("%s", inet_ntoa(ip_souce_address));
        return str;
        //        QString str;
        //        str.sprintf("%02X:%02X:%02X:%02X:%02X:%02X",ether_shost[0],ether_shost[1],ether_shost[2],ether_shost[3],ether_shost[4],ether_shost[5]);
        //        return str;
    }
    QString Getip_destination_address()
    {
        QString str;
        str.sprintf("%s", inet_ntoa(ip_destination_address));
        return str;
    }
    QString Getip_version()
    {
        QString str;
        str.sprintf("IP Version:%d",ip_version);
        /* 获得版本号 */
        return str;
    }
    QString Getip_header_length()
    {
        QString str;
        str.sprintf("Header length:%d", ip_header_length);
        return str;
    }
    QString Getip_tos()
    {
        QString str;
        str.sprintf("TOS:%d", ip_tos);
        return str;
    }
    QString Getip_length()
    {
        QString str;
        str.sprintf("Total length:%d", ntohs(ip_length));
        /* 获得总长度 */
        return str;
    }
    QString Getip_ttl()
    {
        QString str;
        str.sprintf("TTL:%d",ip_ttl);
        /* 获得生存时间 */
        return str;
    }
    QString Getip_off()
    {
        QString str;
        str.sprintf("Offset:%d", (ntohs(ip_off)&0x1fff) *8);
        /* 获得总长度 */
        return str;
    }
    QString Getip_id()
    {
        QString str;
        str.sprintf("Identification:%d", ntohs(ip_id));
        /* 获得标识 */
        return str;
    }
    QString Getip_protocol()
    {
        QString str;
        str.sprintf("Protocol:%d", ip_protocol);
        /* 获得协议类型 */
        return str;
    }
    QString Getip_checksum()
    {
        QString str;
        str.sprintf("Header checksum:%d", ntohs(ip_checksum));
        /* 获得协议类型 */
        return str;
    }
    QTreeWidgetItem * Gettree(){
        QTreeWidgetItem *note = new QTreeWidgetItem(QStringList("IP HEADER"));
        QTreeWidgetItem *childtree1 = new QTreeWidgetItem(QStringList(Getip_version()));
        QTreeWidgetItem *childtree2 = new QTreeWidgetItem(QStringList(Getip_length()));
        QTreeWidgetItem *childtree3 = new QTreeWidgetItem(QStringList(Getip_tos()));
        QTreeWidgetItem *childtree4 = new QTreeWidgetItem(QStringList(Getip_length()));
        QTreeWidgetItem *childtree5 = new QTreeWidgetItem(QStringList(Getip_id()));
        QTreeWidgetItem *childtree6 = new QTreeWidgetItem(QStringList(Getip_off()));
        QTreeWidgetItem *childtree7 = new QTreeWidgetItem(QStringList(Getip_ttl()));
        QTreeWidgetItem *childtree8 = new QTreeWidgetItem(QStringList(Getip_protocol()));
        QTreeWidgetItem *childtree9 = new QTreeWidgetItem(QStringList(Getip_checksum()));
        QTreeWidgetItem *childtree10 = new QTreeWidgetItem(QStringList(Getip_souce_address()));
        QTreeWidgetItem *childtree11 = new QTreeWidgetItem(QStringList(Getip_destination_address()));
        note->addChild(childtree1);
        note->addChild(childtree2);
        note->addChild(childtree3);
        note->addChild(childtree4);
        note->addChild(childtree5);
        note->addChild(childtree6);
        note->addChild(childtree7);
        note->addChild(childtree8);
        note->addChild(childtree9);
        note->addChild(childtree10);
        note->addChild(childtree11);
        return note;
    }

};

/*
-----------------------------------------------------------------------------------------------------------------------
下面是UDP协议格式的定义
-----------------------------------------------------------------------------------------------------------------------
 */

struct udp_header
{
    u_int16_t udp_source_port;
    /* 源端口号 */
    u_int16_t udp_destination_port;
    /* 目的端口号 */
    u_int16_t udp_length;
    /* 长度 */
    u_int16_t udp_checksum;
    /* 校验和 */
public:
    udp_header& operator =(const udp_header& h)
    {
        udp_source_port=h.udp_source_port;
        udp_destination_port=h.udp_destination_port;
        udp_length=h.udp_length;
        udp_checksum=h.udp_checksum;
        return *this;
    }
    QString Getudp_source_port()
    {
        QString str;
        str.sprintf("Destination port:%d", ntohs(udp_source_port));
        return str;
    }
    QString Getudp_destination_port()
    {
        QString str;
        str.sprintf("Source port:%d", ntohs(udp_destination_port));
        return str;
    }
    QString Gettype()
    {
        QString str;
        u_short destination_port;
        destination_port = ntohs(udp_destination_port);
        switch (destination_port)
        {
        case 138:
            str.sprintf("NETBIOS Datagram");
            break;

        case 137:
            str.sprintf("NETBIOS Name");
            break;
        case 139:
            str.sprintf("NETBIOS session");
            break;
        case 53:
            str.sprintf("name-domain server");
            break;
        default:
            str=Getudp_destination_port()+Getudp_source_port()+Getudp_length();
                break; /* 其他的端口号在此没有分析，读者可以在此进一步分析 */
        }
        return str;
    }
    QString Getudp_length()
    {
        QString str;
        str.sprintf("Length:%d", ntohs(udp_length));
        return str;
    }
    QString Getudp_checksum()
    {
        QString str;
        str.sprintf("Checksum:%d", ntohs(udp_checksum));
        return str;
    }
    QTreeWidgetItem * Gettree(){
        QTreeWidgetItem *note = new QTreeWidgetItem(QStringList("UDP HEADER"));
        QTreeWidgetItem *childtree1 = new QTreeWidgetItem(QStringList(Getudp_source_port()));
        QTreeWidgetItem *childtree2 = new QTreeWidgetItem(QStringList(Getudp_destination_port()));
        QTreeWidgetItem *childtree3 = new QTreeWidgetItem(QStringList(Getudp_length()));
        QTreeWidgetItem *childtree4 = new QTreeWidgetItem(QStringList(Getudp_checksum()));
        note->addChild(childtree1);
        note->addChild(childtree2);
        note->addChild(childtree3);
        note->addChild(childtree4);
        return note;
    }
};


/*
-----------------------------------------------------------------------------------------------------------------------
下面是TCP协议格式的定义
-----------------------------------------------------------------------------------------------------------------------
 */

struct tcp_header
{
    u_int16_t tcp_source_port;
    /* 源端口号 */
    u_int16_t tcp_destination_port;
    /* 目的端口号 */
    u_int32_t tcp_acknowledgement;
    /* 序列号 */
    u_int32_t tcp_ack;
    /* 确认码 */
#ifdef WORDS_BIGENDIAN
    u_int8_t tcp_offset: 4,
        /* 偏移 */
        tcp_reserved: 4;
    /* 保留 */
#else
    u_int8_t tcp_reserved: 4,
        /* 保留 */
        tcp_offset: 4;
    /* 偏移 */
#endif
    u_int8_t tcp_flags;
    /* 标记 */
    u_int16_t tcp_windows;
    /* 窗口大小 */
    u_int16_t tcp_checksum;
    /* 校验和 */
    u_int16_t tcp_urgent_pointer;
    /* 紧急指针 */
public:
    tcp_header& operator =(const tcp_header& h)
    {
        tcp_source_port=h.tcp_source_port;
        tcp_destination_port=h.tcp_destination_port;
        tcp_ack=h.tcp_ack;
        tcp_acknowledgement=h.tcp_acknowledgement;
        tcp_reserved=h.tcp_reserved;
        tcp_offset=h.tcp_offset;
        tcp_flags=h.tcp_flags;
        tcp_windows=h.tcp_windows;
        tcp_checksum=h.tcp_checksum;
        tcp_urgent_pointer=h.tcp_urgent_pointer;
        return *this;
    }
    QString Getchecksum()
    {
        QString str;
        str.sprintf("Checksum:%d",ntohs(tcp_checksum));
        return str;
    }
    QString Geturgent_pointer()
    {
        QString str;
        str.sprintf("Urgent pointer:%d",ntohs(tcp_urgent_pointer));
        return str;
    }
    QString GetHeaderLength()
    {
        QString str;
        str.sprintf("Header Length:%d", tcp_offset *4);
        /* 获得首部长度 */
        return str;
    }
    QString Gettcp_reserved()
    {
        QString str;
        str.sprintf("Reserved:%d",tcp_reserved);
        return str;
    }
    QString Gettcp_offset()
    {
        QString str;
        str.sprintf("Offset:%d",tcp_offset);
        return str;
    }
    QString Gettcp_flags()
    {
        QString str;
        u_char flags;
        flags = tcp_flags;
        /* 获得标记 */
        if (flags &0x08)
            str.sprintf("PSH ");
        if (flags &0x10)
            str+="ACK ";
        if (flags &0x02)
            str+="SYN ";
        if (flags &0x20)
            str+="URG ";
        if (flags &0x01)
            str+="FIN ";
        if (flags &0x04)
            str+="RST ";
//        str.sprintf("Source Port:%d", ntohs(tcp_source_port));
        return str;
    }
    QString Getwindows()
    {
        QString str;
        /* 获得窗口大小 */
        str.sprintf("Window Size:%d", ntohs(tcp_windows));
        return str;
    }
    QString Gettype()
    {
        QString str;
        u_short destination_port;
        destination_port = ntohs(tcp_destination_port);
        switch (destination_port)
        {
        case 80:
            str.sprintf("HTTP");
            break;
        case 21:
            str.sprintf("FTP");
            break;
        case 23:
            str.sprintf("TELNET");
            break;
        case 25:
            str.sprintf("SMTP");
            break;
        case 110:
            str.sprintf("POP3");
            break;
        default:
            str=Gettcp_destination_port()+Gettcp_source_port()+Getsequence()+Getacknowledgement();
            break;
        }
        return str;
    }
    QString Gettcp_source_port()
    {
        QString str;
        str.sprintf("Source Port:%d", ntohs(tcp_source_port));
        return str;
    }
    QString Gettcp_destination_port()
    {
        QString str;
        str.sprintf("Destination Port:%d", ntohs(tcp_destination_port));
        return str;
    }
    QString Getsequence()
    {
        QString str;
        str.sprintf("Sequence Number:%u", ntohl(tcp_acknowledgement));
        return str;
    }
    QString Getacknowledgement()
    {
        QString str;
        str.sprintf("Acknowledgement Number:%u", ntohl(tcp_ack));
        return str;
    }
    QTreeWidgetItem * Gettree(){
        QTreeWidgetItem *note = new QTreeWidgetItem(QStringList("TCP HEADER"));
        QTreeWidgetItem *childtree1 = new QTreeWidgetItem(QStringList(Gettcp_source_port()));
        QTreeWidgetItem *childtree2 = new QTreeWidgetItem(QStringList(Gettcp_destination_port()));
        QTreeWidgetItem *childtree4 = new QTreeWidgetItem(QStringList(Getacknowledgement()));
        QTreeWidgetItem *childtree3 = new QTreeWidgetItem(QStringList(Getsequence()));
        QTreeWidgetItem *childtree5 = new QTreeWidgetItem(QStringList(Gettcp_offset()));
        QTreeWidgetItem *childtree6 = new QTreeWidgetItem(QStringList(Gettcp_reserved()));
        // tcp flags get
        QTreeWidgetItem *childtree7 = new QTreeWidgetItem(QStringList(Getwindows()));
        QTreeWidgetItem *childtree8 = new QTreeWidgetItem(QStringList(Getchecksum()));
        QTreeWidgetItem *childtree9 = new QTreeWidgetItem(QStringList(Geturgent_pointer()));
        QTreeWidgetItem *childtree10 = new QTreeWidgetItem(QStringList(Gettcp_flags()));
        note->addChild(childtree1);
        note->addChild(childtree2);
        note->addChild(childtree3);
        note->addChild(childtree4);
        note->addChild(childtree5);
        note->addChild(childtree6);
        note->addChild(childtree7);
        note->addChild(childtree8);
        note->addChild(childtree9);
        note->addChild(childtree10);
        return note;
    }
};
/*
-----------------------------------------------------------------------------------------------------------------------
下面是ICMP协议格式的定义
-----------------------------------------------------------------------------------------------------------------------
 */
struct icmp_header
{
    u_int8_t icmp_type;
    /* ICMP类型 */
    u_int8_t icmp_code;
    /* ICMP代码 */
    u_int16_t icmp_checksum;
    /* 校验和 */
    u_int16_t icmp_id;
    /* 标识 */
    u_int16_t icmp_sequence;
    /* 序列号 */
public:
    icmp_header& operator =(const icmp_header& h)
    {
        icmp_checksum=h.icmp_checksum;
        icmp_code=h.icmp_code;
        icmp_id=h.icmp_id;
        icmp_sequence=h.icmp_sequence;
        icmp_type=h.icmp_type;
        return *this;
    }
    QString Geticmp_type()
    {
        QString str;
        switch (icmp_type)
            /* 根据类型判断ICMP数据包的种类 */
        {
        case 8:
            /* 类型是8，表示是回显请求ICMP数据包 */
            str.sprintf("ICMP Echo Request");
            break;
        case 0:
            /* 类型为0，表示是回显应答ICMP数据包 */
            str.sprintf("ICMP Echo Reply");
            break;
        default:
            break;
            str.sprintf("type_num: %d",icmp_type);
            /* 其它类型的ICMP数据包在此没有分析，读者可以在此添加其它类型的ICMP数据包的分析 */
        }
        return str;
    }
    QString Geticmp_code()
    {
        QString str;
        str.sprintf("ICMP Code:%d", ntohs(icmp_code));
        return str;
    }
    QString Geticmp_checksum()
    {
        QString str;
        str.sprintf("ICMP Checksum:%d", ntohs(icmp_checksum));
        return str;
    }
    QString Geticmp_id()
    {
        QString str;
        str.sprintf("Identifier:%d", ntohs(icmp_id));
        return str;
    }
    QString Geticmp_sequence()
    {
        QString str;
        str.sprintf("Sequence Number:%d", ntohs(icmp_sequence));
        return str;
    }
    QTreeWidgetItem * Gettree(){
        QTreeWidgetItem *note = new QTreeWidgetItem(QStringList("ICMP HEADER"));
        QTreeWidgetItem *childtree1 = new QTreeWidgetItem(QStringList(Geticmp_type()));
        QTreeWidgetItem *childtree2 = new QTreeWidgetItem(QStringList(Geticmp_code()));
        QTreeWidgetItem *childtree3 = new QTreeWidgetItem(QStringList(Geticmp_checksum()));
        QTreeWidgetItem *childtree4 = new QTreeWidgetItem(QStringList(Geticmp_id()));
        QTreeWidgetItem *childtree5 = new QTreeWidgetItem(QStringList(Geticmp_sequence()));
        note->addChild(childtree1);
        note->addChild(childtree2);
        note->addChild(childtree3);
        note->addChild(childtree4);
        note->addChild(childtree5);
        return note;
    }

};

struct packet{
    u_char pkt_con[1600];
    pcap_pkthdr pkt_hdr;
public:
    packet& operator =(const packet& h)
    {
        pkt_hdr=h.pkt_hdr;
        memcpy(pkt_con,h.pkt_con,1600);
        return *this;
    }
};

struct tcpsum{
    struct ether_header eth_hdr;
    struct ip_header    ip_hdr;
    struct tcp_header   tcp_hdr;
    u_char all[1600];
    int tcpnum;
    pcap_pkthdr pkt_hdr;
    QTreeWidgetItem * Gettree(){
        QString str;
        if(pkt_hdr.caplen>54){
            str.sprintf("%s",all+54);
        }else{
            str.sprintf("no other data");
        }
        QTreeWidgetItem *note = new QTreeWidgetItem(QStringList("TCP DATA"));
        QTreeWidgetItem *childtree1 = new QTreeWidgetItem(QStringList(str));
        note->addChild(childtree1);
        return note;
    }

};
struct udpsum{
    struct ether_header eth_hdr;
    struct ip_header    ip_hdr;
    struct udp_header   udp_hdr;
    u_char all[1600];
    int udpnum;
    pcap_pkthdr pkt_hdr;
    QTreeWidgetItem * Gettree(){
        QString str;
        if(pkt_hdr.caplen>42){
            str.sprintf("%s",all+42);
        }else{
            str.sprintf("no other data");
        }
        QTreeWidgetItem *note = new QTreeWidgetItem(QStringList("UDP DATA"));
        QTreeWidgetItem *childtree1 = new QTreeWidgetItem(QStringList(str));
        note->addChild(childtree1);
        return note;
    }
};
struct icmpsum{
    struct ether_header eth_hdr;
    struct ip_header    ip_hdr;
    struct icmp_header  icmp_hdr;
    u_char all[1000];
    int icmpnum;
    pcap_pkthdr pkt_hdr;
    QTreeWidgetItem * Gettree(){
        QString str;
        if(pkt_hdr.caplen>42){
            str.sprintf("%s",all+42);
        }else{
            str.sprintf("no other data");
        }
        QTreeWidgetItem *note = new QTreeWidgetItem(QStringList("ICMP DATA"));
        QTreeWidgetItem *childtree1 = new QTreeWidgetItem(QStringList(str));
        note->addChild(childtree1);
        return note;
    }
};
struct arpsum{
    struct ether_header eth_hdr;
    struct arp_header arp_hdr;
    u_char all[500];
    int arpnum;
    pcap_pkthdr pkt_hdr;
    QTreeWidgetItem * Gettree(){
        QString str;
        if(pkt_hdr.caplen>26){
            str.sprintf("%s",all+26);
        }else{
            str.sprintf("no other data");
        }
        QTreeWidgetItem *note = new QTreeWidgetItem(QStringList("ARP DATA"));
        QTreeWidgetItem *childtree1 = new QTreeWidgetItem(QStringList(str));
        note->addChild(childtree1);
        return note;
    }
};

//static QVector<tcpsum>* tcpack;
//static QVector<udpsum>* udpack;
//static QVector<icmpsum>* icmpack;
//static QVector<arpsum>* arpack;





static int arpn,tcpn,udpn,icmpn=0;
static int packet_number= 1;

static struct tcpsum  alltcp[5000];
static struct udpsum  alludp[5000];
static struct arpsum  allarp[500];
static struct icmpsum allicmp[1000];



static QQueue<packet> que_buf;

















/*
-----------------------------------------------------------------------------------------------------------------------
Libpcap的头文件 ;
下面是以太网协议格式的定义
-----------------------------------------------------------------------------------------------------------------------
*/


/*
=======================================================================================================================
下面是分析TCP协议的函数定义
=======================================================================================================================
 */
void tcp_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content)
{
    struct tcp_header *tcp_protocol;
    /* 定义TCP协议变量 */
    u_char flags;
    /* 标记 */
    int header_length;
    /* 首部长度 */
    u_short source_port;
    /* 源端口号 */
    u_short destination_port;
    /* 目的端口号 */
    u_short windows;
    /* 窗口 */
    u_short urgent_pointer;
    /* 紧急指针 */
    u_int sequence;
    /* 序列号 */
    u_int acknowledgement;
    /* 确认号 */
    u_int16_t checksum;
    /* 校验和 */
    tcp_protocol = (struct tcp_header*)(packet_content + 14+20);
    /* 获得TCP协议数据内容，跳过以太网协议和IP协议部分 */
    source_port = ntohs(tcp_protocol->tcp_source_port);
    /* 获得源端口号 */
    destination_port = ntohs(tcp_protocol->tcp_destination_port);
    /* 获得目的端口号 */
    header_length = tcp_protocol->tcp_offset *4;
    /* 获得首部长度 */
    sequence = ntohl(tcp_protocol->tcp_acknowledgement);
    /* 获得序列号 */
    acknowledgement = ntohl(tcp_protocol->tcp_ack);
    /* 获得确认号 */
    windows = ntohs(tcp_protocol->tcp_windows);
    /* 获得窗口大小 */
    urgent_pointer = ntohs(tcp_protocol->tcp_urgent_pointer);
    /* 获得紧急指针 */
    flags = tcp_protocol->tcp_flags;
    /* 获得标记 */
    checksum = ntohs(tcp_protocol->tcp_checksum);
    /* 获得校验和 */
    printf("-------  TCP Protocol  (Transport Layer)  -------\n");
    printf("Source Port:%d\n", source_port);
    printf("Destination Port:%d\n", destination_port);
    switch (destination_port)
        /* 根据端口号判断应用层协议类型 */
    {
    case 80:
        printf("HTTP protocol\n");
        break;
        /* 上层协议为HTTP协议，可以在此调用分析HTTP协议的函数，读者可以自己尝试实现 */
    case 21:
        printf("FTP protocol\n");
        break;
        /* 上层协议为FTP协议，可以在此调用分析HTTP协议的函数 */
    case 23:
        printf("TELNET protocol\n");
        break;
        /* 上层协议为TELNET协议，可以在此调用分析HTTP协议的函数 */
    case 25:
        printf("SMTP protocol\n");
        break;
        /* 上层协议为SMTP协议，可以在此调用分析HTTP协议的函数 */
    case 110:
        printf("POP3 protocol\n");
        break;
        /* 上层协议为POP3协议，可以在此调用分析HTTP协议的函数 */
    default:
        break; /* 其它的端口号在这里没有分析，读者可以在此分析其它端口号代表的应用层协议 */
    }
    printf("Sequence Number:%u\n", sequence);
    printf("Acknowledgement Number:%u\n", acknowledgement);
    printf("Header Length:%d\n", header_length);
    printf("Reserved:%d\n", tcp_protocol->tcp_reserved);
    printf("Flags:");
    /* 判断标记的种类 */
    if (flags &0x08)
        printf("PSH ");
    if (flags &0x10)
        printf("ACK ");
    if (flags &0x02)
        printf("SYN ");
    if (flags &0x20)
        printf("URG ");
    if (flags &0x01)
        printf("FIN ");
    if (flags &0x04)
        printf("RST ");
    printf("\n");
    printf("Window Size:%d\n", windows);
    printf("Checksum:%d\n", checksum);
    printf("Urgent pointer:%d\n", urgent_pointer);
}
/*
=======================================================================================================================
下面是实现分析UDP协议的函数定义
=======================================================================================================================
 */
void udp_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content)
{
    struct udp_header *udp_protocol;
    /* UDP协议变量 */
    u_short source_port;
    /* 源端口号 */
    u_short destination_port;
    /* 目的端口号 */
    u_short length;
    /* 长度 */
    udp_protocol = (struct udp_header*)(packet_content + 14+20);
    /* 获得UDP协议数据内容，跳过以太网协议和IP协议部分 */
    source_port = ntohs(udp_protocol->udp_source_port);
    /* 获得源端口号 */
    destination_port = ntohs(udp_protocol->udp_destination_port);
    /* 获得目的端口号 */
    length = ntohs(udp_protocol->udp_length);
    /* 获得长度 */
    printf("----------  UDP Protocol  (Transport  Layer)  ----------\n");
    printf("Source port:%d\n", source_port);
    printf("Destination port:%d\n", destination_port);
    switch (destination_port)
        /* 根据端口号来判断应用层协议类型 */
    {
    case 138:
        printf("NETBIOS Datagram Service\n");
        break;
        /*
             * 端口号是138，表示上层协议为NETBIOS
             * 数据报服务，在此可以调用分析此协议的函数，读者自己可以试着实现。
             */
    case 137:
        printf("NETBIOS Name Service\n");
        break;
        /* 端口号是137，表示上层协议为NETBIOS 名字服务，在此可以调用分析此协议的函数 */
    case 139:
        printf("NETBIOS session service\n");
        break;
        /* 端口号是139，表示上层协议为NETBIOS 会话服务，在此可以调用分析此协议的函数。 */
    case 53:
        printf("name-domain server \n");
        break;
        /* 端口号是53，表示上层协议为域名服务，在此可以调用分析此协议的函数。 */
    default:
        break; /* 其他的端口号在此没有分析，读者可以在此进一步分析 */
    }
    printf("Length:%d\n", length);
    printf("Checksum:%d\n", ntohs(udp_protocol->udp_checksum));
    /* 获得校验和 */
}
/*
=======================================================================================================================
下面是实现分析ICMP协议的函数的定义
=======================================================================================================================
 */
void icmp_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content)
{
    struct icmp_header *icmp_protocol;
    /* ICMP协议变量 */
    icmp_protocol = (struct icmp_header*)(packet_content + 14+20);
    /* 获得ICMP协议数据内容，跳过以太网协议和IP协议部分 */
    printf("----------  ICMP Protocol  (Transport Layer)  ----------\n");
    printf("ICMP Type:%d\n", icmp_protocol->icmp_type);
    /* 获得ICMP类型 */
    switch (icmp_protocol->icmp_type)
        /* 根据类型判断ICMP数据包的种类 */
    {
    case 8:
        /* 类型是8，表示是回显请求ICMP数据包 */
        printf("ICMP Echo Request Protocol \n");
        printf("ICMP Code:%d\n", icmp_protocol->icmp_code);
        /* 获得ICMP代码 */
        printf("Identifier:%d\n", icmp_protocol->icmp_id);
        /* 获得标识符 */
        printf("Sequence Number:%d\n", icmp_protocol->icmp_sequence);
        /* 获得序列号 */
        break;
    case 0:
        /* 类型为0，表示是回显应答ICMP数据包 */
        printf("ICMP Echo Reply Protocol \n");
        printf("ICMP Code:%d\n", icmp_protocol->icmp_code);
        /* 获得ICMP代码 */
        printf("Identifier:%d\n", icmp_protocol->icmp_id);
        /* 获得标识符 */
        printf("Sequence Number:%d\n", icmp_protocol->icmp_sequence);
        /* 获得序列号 */
        break;
    default:
        break;
        /* 其它类型的ICMP数据包在此没有分析，读者可以在此添加其它类型的ICMP数据包的分析 */
    }
    printf("ICMP Checksum:%d\n", ntohs(icmp_protocol->icmp_checksum));
    /* 获得校验和 */
}
/*
=======================================================================================================================
下面是实现ARP协议分析的函数定义
=======================================================================================================================
 */
void arp_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content)
{
    struct arp_header *arp_protocol;
    /* ARP协议变量 */
    u_short protocol_type;
    /* 协议类型 */
    u_short hardware_type;
    /* 硬件类型 */
    u_short operation_code;
    /* 操作码 */
    u_char *mac_string;
    /* 以太网地址 */
    struct in_addr source_ip_address;
    /* 源IP地址 */
    struct in_addr destination_ip_address;
    /* 目的IP地址 */
    u_char hardware_length;
    /* 硬件地址长度 */
    u_char protocol_length;
    /* 协议地址长度 */
    printf("--------   ARP Protocol (Network Layer)    --------\n");
    arp_protocol = (struct arp_header*)(packet_content + 14);
    allarp[arpn].arp_hdr=*arp_protocol;
    allarp[arpn].arpnum=arpn;
    memcpy(allarp[arpn].all,(char*)packet_content,packet_header->len);


    printf("\n---------------------------------------------------------------------------\n");
    int total=packet_header->caplen; int i=0;
    u_char *alltemp=(u_char*)allarp[arpn].all;
    while(i<total){
        printf("%02x ",*alltemp);
        alltemp++;i++;
    }
    printf("\n---------------------------------------------------------------------------\n");

    /* 获得ARP协议数据内容，跳过以太网协议部分 */
    hardware_type = ntohs(arp_protocol->arp_hardware_type);
    /* 获得硬件类型 */
    protocol_type = ntohs(arp_protocol->arp_protocol_type);
    /* 获得协议类型 */
    operation_code = ntohs(arp_protocol->arp_operation_code);
    /* 获得操作码 */
    hardware_length = arp_protocol->arp_hardware_length;
    /* 获得硬件地址长度 */
    protocol_length = arp_protocol->arp_protocol_length;
    /* 获得协议地址长度 */
    printf("ARP Hardware Type:%d\n", hardware_type);
    printf("ARP Protocol Type:%d\n", protocol_type);
    printf("ARP Hardware Length:%d\n", hardware_length);
    printf("ARP Protocol Length:%d\n", protocol_length);
    printf("ARP Operation:%d\n", operation_code);
    switch (operation_code) /* 根据操作码判断ARP协议类型 */
    {
    case 1:
        printf("ARP Request Protocol\n");
        break;
        /* 操作码为1，表示是ARP请求协议 */
    case 2:
        printf("ARP Reply Protocol\n");
        break;
        /* 操作码为2，表示是ARP应答协议 */
    case 3:
        printf("RARP Request Protocol\n");
        break;
        /* 操作码为3，表示是RARP请求协议 */
    case 4:
        printf("RARP Reply Protocol\n");
        break;
        /* 操作码为4，表示是RARP应答协议 */
    default:
        break;
    }
    printf("Ethernet Source Address is : \n");
    mac_string = arp_protocol->arp_source_ethernet_address;
    printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));
    /* 获得源以太网地址 */
    memcpy((void*) &source_ip_address, (void*) &arp_protocol->arp_source_ip_address, sizeof(struct in_addr));
    //struct in_addr1 ipaddr;
    //ipaddr = source_ip_address;
    //printf("Source address:%d.%d.%d.%d\n",ipaddr.S_un_b.s_b1,ipaddr.S_un_b.s_b2,ipaddr.S_un_b.s_b3,ipaddr.S_un_b.s_b4);
    printf("Source IP Address:%s\n", inet_ntoa(source_ip_address));
    /* 获得源IP地址 */
    printf("Ethernet Destination Address is : \n");
    mac_string = arp_protocol->arp_destination_ethernet_address;
    printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));
    /* 获得目的以太网地址 */
    memcpy((void*) &destination_ip_address, (void*) &arp_protocol->arp_destination_ip_address, sizeof(struct in_addr));
    //ipaddr = destination_ip_address;
    //printf("Destination IP Address:%d.%d.%d.%d\n",ipaddr.S_un_b.s_b1,ipaddr.S_un_b.s_b2,ipaddr.S_un_b.s_b3,ipaddr.S_un_b.s_b4);
    printf("Destination IP Address:%s\n", inet_ntoa(destination_ip_address));
    /* 获得目的IP地址 */
}
/*
=======================================================================================================================
下面是实现分析IP协议的函数定义
=======================================================================================================================
 */
void ip_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content)
{
    //    u_char *all=(u_char*)packet_content;
    //char *packet_content1= (char)(*packet_content);
    struct ip_header *ip_protocol;
    //printf("%s\n",packet_content);
    /* IP协议变量 */
    u_int header_length;
    /* 首部长度 */
    u_int offset;
    /* 偏移 */
    char tos;
    /* 服务质量 */
    u_int16_t checksum;
    /* 校验和 */
    ip_protocol = (struct ip_header*)(packet_content + 14);
    /* 获得IP协议数据内容，跳过以太网协议部分 */
    checksum = ntohs(ip_protocol->ip_checksum);
    /* 获得校验和 */
    header_length = ip_protocol->ip_header_length *4;
    /* 获得IP首部长度 */
    tos = ip_protocol->ip_tos;
    /* 获得服务质量 */
    offset = ntohs(ip_protocol->ip_off);
    /* 活动偏移 */
    printf("----------- IP Protocol  (Network Layer)  -----------\n");
    printf("IP Version:%d\n", ip_protocol->ip_version);
    /* 获得版本号 */
    printf("Header length:%d\n", header_length);
    printf("TOS:%d\n", tos);
    printf("Total length:%d\n", ntohs(ip_protocol->ip_length));
    /* 获得总长度 */
    printf("Identification:%d\n", ntohs(ip_protocol->ip_id));
    /* 获得标识 */
    printf("Offset:%d\n", (offset &0x1fff) *8);
    printf("TTL:%d\n", ip_protocol->ip_ttl);
    /* 获得生存时间 */
    printf("Protocol:%d\n", ip_protocol->ip_protocol);
    /* 获得协议类型 */
    switch (ip_protocol->ip_protocol)
        /* 根据协议类型判断上层协议类型 */
    {
    case 6:
    {
        printf("The Transport Layer Protocol is TCP\n");
        tcpn++;
        alltcp[tcpn].eth_hdr=*((struct ether_header*)packet_content);
        alltcp[tcpn].ip_hdr=*(ip_protocol);
        alltcp[tcpn].tcp_hdr=*((struct tcp_header*)(packet_content + 14+20));
        alltcp[tcpn].tcpnum=tcpn;
        memcpy(alltcp[tcpn].all,(char*)packet_content,packet_header->len);
        alltcp[tcpn].pkt_hdr=*packet_header;
        //                struct tcpsum temp;
        //                temp.all=(char*)malloc(sizeof(packet_content));
        //                memcpy(temp.all,packet_content,sizeof(packet_content));
        //                *(temp.eth_hdr)=(struct ether_header)(*packet_content);
        //                temp.eth_hdr=(struct ether_header *)(all);
        //                temp.ip_hdr=(struct ip_header *)(all + 14);
        //                temp.tcp_hdr=(struct tcp_header *)(all + 14 + 20);
        //                temp.all=(char *)all;
        //                temp.tcpnum++;
        //                tcpack->append(temp);
        //printf("Destination address:%s\n", inet_ntoa(tcpack->at(0).ip_hdr->ip_destination_address));

    }
        break;
        /* 上层协议为TCP协议 */
    case 17:
    {
        printf("The Transport Layer Protocol is UDP\n");
        udpn++;
        alludp[udpn].eth_hdr=*((struct ether_header*)packet_content);
        alludp[udpn].ip_hdr=*(ip_protocol);
        alludp[udpn].udp_hdr=*((struct udp_header*)(packet_content + 14+20));
        alludp[udpn].udpnum=udpn;
        memcpy(alludp[udpn].all,(char*)packet_content,packet_header->len);
        alludp[udpn].pkt_hdr=*packet_header;
        //                struct udpsum temp;
        //                temp.eth_hdr=(struct ether_header*)packet_content;
        //                temp.ip_hdr=(struct ip_header*)(packet_content + 14);
        //                temp.udp_hdr=(struct udp_header*)(packet_content + 14+20);
        //                temp.all=(char *)(packet_content+14+20+8);
        //                temp.udpnum++;
        //                udpack->append(temp);
    }
        break;
        /* 上层协议为UDP协议 */
    case 1:
    {
        printf("The Transport Layer Protocol is ICMP\n");
        icmpn++;
        allicmp[icmpn].eth_hdr=*((struct ether_header*)packet_content);
        allicmp[icmpn].ip_hdr=*(ip_protocol);
        allicmp[icmpn].icmp_hdr=*((struct icmp_header*)(packet_content + 14+20));
        allicmp[icmpn].icmpnum=icmpn;
        memcpy(allicmp[icmpn].all,(char*)packet_content,packet_header->len);
        allicmp[icmpn].pkt_hdr=*packet_header;
        //                struct icmpsum temp;
        //                temp.eth_hdr=(struct ether_header*)packet_content;
        //                temp.ip_hdr=(struct ip_header*)(packet_content + 14);
        //                temp.icmp_hdr=(struct icmp_header*)(packet_content+14+20);
        //                temp.all=(char *)(packet_content+14+20+8);
        //                temp.icmpnum++;
        //                icmpack->append(temp);
    }
        break;
        /* 上层协议为ICMP协议 */
    default:
        break;
    }
    printf("Header checksum:%d\n", checksum);
    /* 校验和 */

    //printf("%d.%d.%d.%d\n", inet_ntoa(*ipaddr),  inet_ntoa(*ipaddr+2), inet_ntoa(*ipaddr+4), inet_ntoa(*ipaddr+6));
    //sprintf(List.sIP,"%d.%d.%d.%d",ipaddr.S_un.S_un_b.s_b1,ipaddr.S_un.S_un_b.s_b2,ipaddr.S_un.S_un_b.s_b3,ipaddr.S_un.S_un_b.s_b4);

    printf("Source address:%s\n", inet_ntoa(ip_protocol->ip_souce_address));
    printf("Destination address:%s\n", inet_ntoa(ip_protocol->ip_destination_address));
    /* 获得源IP地址 */
    //struct in_addr1 ipaddr;
    //ipaddr = (char *) ip_protocol->ip_souce_address;
    //printf("Source address:%d.%d.%d.%d\n",ipaddr.S_un_b.s_b1,ipaddr.S_un_b.s_b2,ipaddr.S_un_b.s_b3,ipaddr.S_un_b.s_b4);
    /* 获得目的IP地址 */
    //ipaddr = ip_protocol->ip_destination_address;
    //printf("Destination address:%d.%d.%d.%d\n",ipaddr.S_un_b.s_b1,ipaddr.S_un_b.s_b2,ipaddr.S_un_b.s_b3,ipaddr.S_un_b.s_b4);


    switch (ip_protocol->ip_protocol)
        /* 判断上层协议类型，然后调用相应的函数进行分析 */
    {
    case 6:
        /* 上层协议为TCP协议 */
        tcp_protocol_packet_callback(argument, packet_header, packet_content);
        break;
        /* 调用分析TCP协议的函数，注意参数的传递，表示分析的是同一个网络数据包 */
    case 17:
        /* 上层协议为UDP协议 */
        udp_protocol_packet_callback(argument, packet_header, packet_content);
        break;
        /* 调用分析UDP协议的函数，注意参数的传递方式 */
    case 1:
        /* 上层协议为ICMP协议 */
        icmp_protocol_packet_callback(argument, packet_header, packet_content);
        break;
        /* 调用分析ICMP协议的函数，注意参数的传递 */
    default:
        break;
        /* 其他类型的协议在此没有分析，读者可以在此进一步分析其它传输层协议 */
    }
}

/*
=======================================================================================================================
下面是主函数的定义
=======================================================================================================================
 */




/*
=======================================================================================================================
下面是分析以太网协议的函数定义，同时它也是回调函数
=======================================================================================================================
 */
void ethernet_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content)
{
    //    QFile f("/home/lis/dev/cmd/test.txt");
    //    if(!f.open(QIODevice::WriteOnly | QIODevice::Text))
    //    {
    //        printf("no file test.txt");
    //    }
    //    QTextStream txtout(&f);
    //    txtout <<(* packet_content)<< endl;
    //    f.close();
    int total=packet_header->caplen; int i=0;
    u_char *all=(u_char*)packet_content;
    while(i<total){
        printf("%02x ",*all);
        all++;i++;
    }
    printf("\n---------------555-----------------\n");
    int j=0;
    u_char *all1=(u_char*)packet_content;

    while(j<total){
        printf("%c",*all1);
        all1++;j++;
    }
//    QString str;
//    str.fromLocal8Bit(all1);
//    printf("%s",all1);
//    printf("\n---------------666-----------------\n");

    printf("\n---------------777-----------------\n");
    u_short ethernet_type;
    /* 以太网类型 */
    struct ether_header *ethernet_protocol;
    /* 以太网协议变量 */
    u_char *mac_string;
    /* 以太网地址 */

    printf("**************************************************\n");
    printf("The %d  packet is captured.\n", packet_number);
    printf("--------   Ehternet Protocol (Link Layer)    --------\n");
    ethernet_protocol = (struct ether_header*)packet_content;
    /* 获得以太网协议数据内容 */
    printf("Ethernet type is :\n");
    ethernet_type = ntohs(ethernet_protocol->ether_type);
    /* 获得以太网类型 */
    printf("%04x\n", ethernet_type);
    switch (ethernet_type)
        /* 根据以太网类型字段判断上层协议类型 */
    {
    case 0x0800:
    {
        printf("The network layer is IP protocol\n");
    }
        break;
        /* 上层协议为IP协议 */
    case 0x0806:
    {
        arpn++;
        printf("The network layer is ARP protocol\n");
        allarp[arpn].eth_hdr = (*ethernet_protocol);
        allarp[arpn].pkt_hdr=*packet_header;
    }
        break;
        /* 上层协议为ARP协议 */
    case 0x8035:
        printf("The network layer is RARP protocol\n");
        // process rarp[allrarp]
        break;
        /* 上层协议为RARP协议 */
    default:
        //process  othereth[alloeth]
        break;
    }
    printf("Mac Source Address is : \n");
    mac_string = ethernet_protocol->ether_shost;
    printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));
    /* 获得源以太网地址 */
    printf("Mac Destination Address is : \n");
    mac_string = ethernet_protocol->ether_dhost;
    printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));
    /* 获得目的以太网地址 */
    switch (ethernet_type)
        /* 根据以太网类型字段判断上层协议，然后调用相应函数进行分析 */
    {
    case 0x0806:
        /* 上层是ARP协议 */arp_protocol_packet_callback(argument, packet_header, packet_content);
        break;
        /* 调用分析ARP协议的函数 */
    case 0x0800:
        /* 上层是IP协议 */ip_protocol_packet_callback(argument, packet_header, packet_content);
        break;
        /* 调用分析IP协议的函数 */
    default:
        break; /* 其它的协议在此没有分析，读者可以试着进一步分析 */
    }
    printf("**************************************************\n");
    packet_number++;
}


void out_to_queue(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content){
    if(open_close){
        capture_num++;
        struct packet ptk;
        memcpy(ptk.pkt_con,(char*)packet_content,packet_header->len);
        ptk.pkt_hdr=(*packet_header);
        pthread_mutex_lock(&mylock);
        que_buf.enqueue(ptk);
        pthread_mutex_unlock(&mylock);
    }
}
//void  * begin_capture(void *){

//    pcap_t *pcap_handle;
//    /* libpap句柄 */
//    char error_content[PCAP_ERRBUF_SIZE];
//    /* 存储错误内容 */
//    char *net_interface;
//    /* 网络接口 */
//    struct bpf_program bpf_filter;
//    /* BPF过滤规则 */
//    char bpf_filter_string[] = "";
//    /* 过滤规则字符串，此时为空的，表示捕获所有的网络数据包，而不是捕获特定的网络数据包 */
//    bpf_u_int32 net_mask;
//    /* 网络掩码 */
//    bpf_u_int32 net_ip;
//    /* 网络地址 */
//    //net_interface = pcap_lookupdev(error_content);
//    net_interface="wlan0";
//    /* 获得网络接口 */
//    pcap_lookupnet(net_interface, &net_ip, &net_mask, error_content);
//    /* 获得网络地址和网络掩码 */
//    pcap_handle = pcap_open_live(net_interface, BUFSIZ, 1, 0, error_content);
//    /* 打开网络接口 */
//    pcap_compile(pcap_handle, &bpf_filter, bpf_filter_string, 0, net_ip);
//    /* 编译过滤规则 */
//    pcap_setfilter(pcap_handle, &bpf_filter);
//    /* 设置过滤规则 */
//    if (pcap_datalink(pcap_handle) != DLT_EN10MB)
//        return 0;

//    struct timeval tv;
//    gettimeofday(&tv,NULL);

//    cap_stime=tv.tv_sec+double(tv.tv_usec/double(1000000));

//    pcap_loop(pcap_handle,  -1, out_to_queue, NULL);
//    /* 注册回调函数，循环捕获网络数据包，然后调用回调函数对捕获的网络数据包进行分析 */

//    pcap_close(pcap_handle);
//}



void MyThread::run()
{
    while(process_or_not){
        if (!que_buf.isEmpty()) {
            pthread_mutex_lock(&mylock);
            struct packet b=que_buf.dequeue();
            pthread_mutex_unlock(&mylock);
            printf("\n--------2-----\n");
            pthread_mutex_lock(&mutex1);
            ethernet_protocol_packet_callback(0,&b.pkt_hdr, b.pkt_con);
            emit notify();
            sem_post(&mutex2);
//            this->sleep(50);

        }else{
            continue;

        }

    }
}






void MyThread1::run()
{
    pcap_t *pcap_handle;
    /* libpap句柄 */
    char error_content[PCAP_ERRBUF_SIZE];
    /* 存储错误内容 */
    char *net_interface;
    /* 网络接口 */
    struct bpf_program bpf_filter;
    /* BPF过滤规则 */
    char *bpf_filter_string = "";

    QString  str=netstr;
    QByteArray ba = str.toLatin1();
    net_interface=ba.data();
    str=filterstr;ba = str.toLatin1();
    bpf_filter_string=ba.data();

    /* 过滤规则字符串，此时为空的，表示捕获所有的网络数据包，而不是捕获特定的网络数据包 */
    bpf_u_int32 net_mask;
    /* 网络掩码 */
    bpf_u_int32 net_ip;
    /* 网络地址 */
    //net_interface = pcap_lookupdev(error_content);
//    net_interface="wlan0";
    /* 获得网络接口 */
    pcap_lookupnet(net_interface, &net_ip, &net_mask, error_content);
    /* 获得网络地址和网络掩码 */
    pcap_handle = pcap_open_live(net_interface, BUFSIZ, 1, 0, error_content);
    /* 打开网络接口 */
    pcap_compile(pcap_handle, &bpf_filter, bpf_filter_string, 0, net_ip);
    /* 编译过滤规则 */
    pcap_setfilter(pcap_handle, &bpf_filter);
    /* 设置过滤规则 */
    if (pcap_datalink(pcap_handle) != DLT_EN10MB)
        return;

    struct timeval tv;
    gettimeofday(&tv,NULL);

    cap_stime=tv.tv_sec+double(tv.tv_usec/double(1000000));

    pcap_loop(pcap_handle,  -1, out_to_queue, NULL);
    /* 注册回调函数，循环捕获网络数据包，然后调用回调函数对捕获的网络数据包进行分析 */

    pcap_close(pcap_handle);
}


#endif
